How To Code A Disk Mag

Javier Loureiro

<derethor@arrakis.es>

Introduction

During last year, a friend and I were coding a disk mag. We had some troubles and delays (as in all systems that I coded :), but I learned some very interesting things. I wrote this article for people who want to code another one, helping to support the amiga scene.

Here, I won't to explain how to release it, and how to get articles, etc... I only was one of the coders, and this article is for them. It is hard to code a diskmag without a group to make the gfx and music for you, so this article is for the scene coders.

Well, Let's start!

The main language was C (no object oriented) and 680x0 asm to hard specific parts. We tried to make the code OS friendly, but a lot of parts aren't (especially the copper, and the music, of course).

The mag is a simple file, and it is very easy to install in HD. Only the fonts aren't in the main one. So, at last 2Mb of ram is needed to run the program.

Functions

The main() function is very easy:

main()
    {
        init();
        handle();
        end();
    }

We initialize music, system, interrupts, and other things. And we handle the input messages that the user sends us. When the user wants to quit, we restore the system.

Handle : Calls an asm function that tests mouse movements, key presses, mouse clicks and the joystick :). Returns a number that is the message that the user sent. This function isn't an interrupt, and doesn't use them. It moves the mouse, so if you press a button, you can't move the pointer during the execution of the function. Also, it returns the last key pressed, and updates the mouse coordinates.

When the asm function returns a value, the code enters a big case block to determine which function to call. If the user clicks, test if a button is bottom. If the user presses a key, make another case...

void handle(void)
{
    test();	/* Check for the user's message */
    while(quit)
    {
        switch(flag)
        {
            case KEY : 
                switch(key)
                {
                    case UP : go up!
                    case DOWN : go down!
                    case M : toggle music!
                }
                break;
            case LEFTBUTTON :
                checkbutton()
                switch(button)
                {
                    case MENU : prints menu!
                    case MUSIC : toggle music!
                }
                break;
       	}
    }
}

Of course, our finish routine is more and more complicated, but at the start it was very similar, and we will add new features while the program is in development.

Interface

We like to use the graphics.library features, so we dont need to write a lot of blitter code.

Let's define a rastport structure, filling in the bitplane adresses. Use the AllocRaster() function of the library. Later, we load a copperlist (in asm) with the bitplane struct...

Now, we have a rastport to use Text(), DrawImage(), etc... and we don't need to use complicated blitter routines.

The use of graphics.library simplifies a lot the work, and helps us to make more complicated text routines, etc...

Text

The writearticle() function writes current article in the rastport (of course :). Note that current is a global variable.

First, we clear the text, update the fields (author, section, page), and start to print the text.

In the text there are some codes to change the display:

The use of move and text is very easy to use for this function.

When we find a link, we add a button to the list. So, the main menu it is very easy to configure. The link says where to jump. In the handle() function, we check if the mouse is in a link, and change the colour, so the user knows that is a link. Of course, the colour of a link may be different to the rest (we use a colour only for links). At last, in the begining of each writearticle(), we clear the last links from object table.

If we want to write the next page, we only put:

    if(currentpage++<lastpage)
        writearticle();

and so on.

Buttons

We use DrawImage() to this purpose. In a separate module we define a an Image structure for each button, and if we press one, we draw another button.

In the screen init, we add it to the object table, giving the corners of the image, in absolute coordinates.

To check if the mouse press is a button (and a link to another article) we compare the mouse coords with all buttons in the object table.

Interrupts

We only use the vblank interrupt. Only to make a colour fade, and play music. Use AddIntServer(), to this purpose.

Music

Not very complicated. Use a module player in the vblank interrupt.

Data Structures

Use a struct for the page:

    struct page {
        UBYTE   *text;
        UWORD   other attributes;
        }

An article is an array of pages:
    struct article {
        struct page ar_page[MAXPAGE];
        UWORD       other attributes;
        }

Also, a button:
    struct button {
        struct Image    *image;
        WORD            x;
        WORD            y;
        }

All global variables are in a struct:
    struct Data {
        UWORD   Currentpage;
        UWORD   Currentarticle;
        UWORD   others...
        }

Finish

To code a mag, we need a lot of planification, and not a lot of code. When we have the main ideas, we make the display and the rastport. Later the handle() and the writearticle(). Go on adding new features in the case's, to the release.


Credits

Ceibe mag was coded by Jose Manuel Rodriguez and Javier Loureiro.

If you like to contact by email: Jose Manuel Rodriguez <josema@dc.fi.udc.es>
Javier Loureiro <derethor@arrakis.es>

Table of Contents